/**
 * Project Name:fastPlat
 * File Name:MdDataServiceImpl.java
 * Package Name:com.fast.cms.service.article.impl
 * Date:2018年08月26日 09时59分43秒
 * Copyright (c) 2018, lsflu@126.com All Rights Reserved.
 *
*/

package com.fast.cms.service.article.impl;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.fast.base.cache.MemcachedUtils;
import com.fast.base.dao.MybatisDao;
import com.fast.base.dao.daoSuport.JpaDaoSupport;
import com.fast.base.db.page.PageView;
import com.fast.base.db.page.QueryResult;
import com.fast.base.db.sql.impl.SqlGeneratorImpl;
import com.fast.base.util.DateUtils;
import com.fast.base.util.LogUtils;
import com.fast.base.util.data.MathUtils;
import com.fast.base.util.file.FileIoUtils;
import com.fast.cms.model.article.BatchDataInfo;
import com.fast.cms.model.article.MdData;
import com.fast.cms.service.article.MdDataService;
import com.fast.cms.service.system.SysLogService;
import com.fast.cms.web.form.BatchDataInfoListForm;
import com.fast.cms.web.form.MdDataForm;
import com.fast.common.CacheConstant;
import com.fast.common.userCache.AdminCacheUtils;
import com.fast.user.model.admin.AdminUser;
import com.fast.user.model.admin.SysLog;

/**
 * ClassName:MdDataServiceImpl <br/>
 * 用途: MdData服务实现 <br/>
 * 开发人员：lushuifa  http://lushuifa.iteye.com/
 * 邮箱:lsflu@126.com
 * @version  1.0
 * @since    JDK 1.6
 * @see
 * Date:     2018年08月26日 09时59分43秒 <br/> 	 
 */
@Service("mdDataService")
public class MdDataServiceImpl extends JpaDaoSupport implements MdDataService {
	
	@Resource(name="sysLogService")
	protected SysLogService logS;
	
	@Autowired
	private MybatisDao mybatisDao01;

    /**
	 * 分页获取MdData列表
	 * @return PageView<MdData>
	 */
	@Override
	public PageView<MdData> getMdDataList(MdDataForm mdDataForm){
		mdDataForm.setStartIndex((mdDataForm.getPage()-1)*mdDataForm.getRows());
		int queryCount = super.getSession().selectOne("mdData.getMdDataCount", mdDataForm);
		List<MdData> batchDataList = super.getSession().selectList("mdData.getMdDataList", mdDataForm );
		for (MdData mdData : batchDataList) {
			String dataTitle = mdData.getDataTitle();
			if (mdData.getValidateFlag()==0) {
				String titleGanCi = mdData.getTitleGanCi();
	        	if(StringUtils.isNotBlank(titleGanCi)){
	            	String[] titleGanCiArray = titleGanCi.split(",");
	            	for (int i = 0; i < titleGanCiArray.length; i++) {
	            		dataTitle =  dataTitle.replaceAll(titleGanCiArray[i],"<font color=red><b>"+titleGanCiArray[i]+"</b></font>");
					}
	        	}
	        	
	        	String pingpaiGanCi = mdData.getPingpaiGanCi();
	        	if(StringUtils.isNotBlank(pingpaiGanCi)){
	            	String[] pingpaiGanCiArray = pingpaiGanCi.split(",");
	            	for (int i = 0; i < pingpaiGanCiArray.length; i++) {
	            		dataTitle = dataTitle.replaceAll(pingpaiGanCiArray[i],"<font color=red><b>"+pingpaiGanCiArray[i]+"</b></font>");
					}
	        	}
			}
        	mdData.setDataTitleVmg(dataTitle);
		}
		QueryResult<MdData> queryResult = new QueryResult<MdData>();
		queryResult.setResultList(batchDataList);
		queryResult.setTotalRecord(queryCount);
		PageView<MdData> pageView = new PageView<MdData>();
	    pageView.setCurrentPage(mdDataForm.getPage());
		pageView.setQueryResult(queryResult);
 		return pageView;
	}
	
	/**
	 * 说明:敏感词列表 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年9月1日 下午6:46:04 </pre>
	 * @param 
	 * @return PageView<MdData> 说明
	 */
	public PageView<Map<String, Object>> getMianGanList(){
		List<Map<String, Object>> dataList = super.getSession().selectList("mdData.getMianganList",null);
		Set<String> setList = new HashSet<String>();
		for (Map<String, Object> dataMap : dataList) {
			String titleGanCi = (String) dataMap.get("titleGanCi");
			String pingpaiGanCi = (String) dataMap.get("pingpaiGanCi");
			if (StringUtils.isNotBlank(titleGanCi)) {
				String[] titleGanCiArray = titleGanCi.split(",");
				for (String str : titleGanCiArray) {
					setList.add(str);
				}
			}
			
			if (StringUtils.isNotBlank(pingpaiGanCi)) {
				String[] pingpaiGanCiArray = pingpaiGanCi.split(",");
				for (String str : pingpaiGanCiArray) {
					setList.add(str);
				}
			}
		}
		List<Map<String, Object>> dataList2 = new ArrayList<Map<String, Object>>();
		Map<String, Object> dataMap = null;
		Iterator<String> it = setList.iterator();  
		int id = 1;
		while (it.hasNext()) {  
			  String str = it.next();  
			  dataMap = new HashMap<String, Object>();
			  dataMap.put("id", id);
			  dataMap.put("mianganCi", str);
			  dataList2.add(dataMap);
			  id++;
		}  
		QueryResult<Map<String, Object>>  queryResult = new QueryResult<Map<String, Object>>();
		queryResult.setResultList(dataList2);
		queryResult.setTotalRecord(dataList2.size());
		PageView<Map<String, Object>> pageView = new PageView<Map<String, Object>>();
	    pageView.setCurrentPage(1);
		pageView.setQueryResult(queryResult);
 		return pageView;
	}
	
	/**
	 * 说明: 获取批次列表 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年8月26日 下午5:25:10 </pre>
	 * @param 
	 * @return PageView<MdData> 说明
	 */
	public PageView<BatchDataInfo> getBatchDataInfoList(BatchDataInfoListForm batchDataInfoListForm){
		int startIndex = (batchDataInfoListForm.getPage()-1)*batchDataInfoListForm.getRows();
	    int pageSize = batchDataInfoListForm.getRows();
		Map<String, Object> parameter = new HashMap<String,Object>();
		parameter.put("startIndex", startIndex);
		parameter.put("pageSize", pageSize);
		String order = batchDataInfoListForm.getOrder();
		String sort = batchDataInfoListForm.getSort();
		if (StringUtils.isBlank(order)&&StringUtils.isBlank(sort)) {
			parameter.put("order", "desc");
			parameter.put("sort", "batchCount");
		}else {
			parameter.put("order", order);
			parameter.put("sort", sort);
		}
		
		int queryCount = super.getSession().selectOne("mdData.getBatchDataInfoCount", parameter);
		List<BatchDataInfo> batchDataList = super.getSession().selectList("mdData.getBatchDataInfoList", parameter );
		QueryResult<BatchDataInfo> queryResult = new QueryResult<BatchDataInfo>();
		queryResult.setResultList(batchDataList);
		queryResult.setTotalRecord(queryCount);
		PageView<BatchDataInfo> pageView = new PageView<BatchDataInfo>();
	    pageView.setCurrentPage(batchDataInfoListForm.getPage());
		pageView.setQueryResult(queryResult);
 		return pageView;
	}
	
	/**
	 * 说明: 导入数据 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年8月26日 上午10:12:39 </pre>
	 * @param 
	 * @return boolean 说明
	 */
	public String batchSaveMdDataByImpFile(String fileDiskPath,String dataTypeId,AdminUser loginUser) {
		String key = CacheConstant.getLockKey("importDataFromTxt");
		try {
			int total = FileIoUtils.getFileLineNumber(fileDiskPath);
			int pageSize = 20000;
	        int totalPage = (int) (total % pageSize == 0 ? (total / pageSize) : (total/ pageSize + 1));
			int page = 1;
	        StringBuffer sBuffer = new StringBuffer();
			while (page<=totalPage) {
				String result = mdDataExecutorService(total, page,pageSize, fileDiskPath,loginUser);
				LogUtils.info("===================第"+page+"页=====================");
				sBuffer.append(result);
				page++;
			}
	        //添加上传记录
	        SysLog sysLog = new SysLog();
	        fileDiskPath = fileDiskPath.replace("\\", "/");
	        fileDiskPath = fileDiskPath.substring(fileDiskPath.lastIndexOf("/")+1, fileDiskPath.length());
	        sysLog.setActionName(fileDiskPath);
	        sysLog.setLogData(total+"");
	        sysLog.setOperator(loginUser.getRealName());
	        sysLog.setLogDate(DateUtils.getNow());
	        sysLog.setLogType("mdData_upload");
	        logS.persist(sysLog);
	        MemcachedUtils.delete(key);
	        return sBuffer.toString();
		} catch (Exception e) {
			e.printStackTrace();
			MemcachedUtils.delete(key);
			return "";
		}
	}
	
	public String checkReaptDataFile(String fileDiskPath) {
		try {
			BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(fileDiskPath),"UTF-8"));   
			LineNumberReader lnr=new LineNumberReader(br);
			String line=null;
			StringBuffer repeatResult = new StringBuffer();
			while((line=lnr.readLine())!=null)
			{   
				String dataUrl = line;
				int count = super.getSession().selectOne("countDataUrl", dataUrl);
				if (count>0) {
					repeatResult.append(line+"<br/>");
				}
			}
			lnr.close();
			return repeatResult.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * 说明:执行批次数量更新 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年9月9日 上午10:39:14 </pre>
	 * @param 
	 * @return void 说明
	 */
	public String mdDataExecutorService(int total,int page,int pageSize,String filePath, AdminUser loginUser) {
		try {
			int startIndex = (page-1)*pageSize;
			int endIndex = startIndex + pageSize;
			if (endIndex > total) {
				endIndex = total;
			}
			LogUtils.info("startIndex:"+startIndex+" endIndex:"+endIndex);
			BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"UTF-8"));   
			LineNumberReader lnr=new LineNumberReader(br);
			lnr.setLineNumber(startIndex);
			String line=null;
			MdData mdData = null;
			StringBuffer repeatResult = new StringBuffer();
			while((line=lnr.readLine())!=null)
			{
				int lineNumber = lnr.getLineNumber();
				mdData = new MdData();
				String[] lineArray = line.replace("$$", "`").split("`");
				mdData = new MdData();
				String uuid = MathUtils.getTheOnlyStr();
				mdData.setUuid(uuid);
				mdData.setDataUrl(lineArray[0]);
				mdData.setDataTitle(lineArray[1]);
				mdData.setDataType("");
				mdData.setCreater(loginUser.getRealName());
				mdData.setCreaterId(loginUser.getId());
				mdData.setCreateTime(new Date());
				mdData.setEditorId(loginUser.getId());
				mdData.setEditorName(loginUser.getRealName());
				mdData.setEditTime(new Date());
				mdData.setValidateFlag(0);
				//敏感词过滤
				mdData.setTitleGanCi(fileterTitleGanCi(mdData.getDataTitle()));
				mdData.setPingpaiGanCi(fileterPingPaiGanCi(mdData.getDataTitle()));
				try {
					LogUtils.info("================正 在保存第【"+lineNumber+"】条数据===============================================");
				    mybatisDao01.getSession().insert("mdData.insertMdData", mdData);
				} catch (DuplicateKeyException e) {
					LogUtils.info(mdData.getDataTitle()+":"+e.getMessage());
					LogUtils.info("================第【"+lineNumber+"】条数据存在重复===============================================");
					repeatResult.append(lineNumber+",");
				}
			    if (lineNumber==endIndex) {
			    	break;
				}
			}
			lnr.close();
			updateBatchCountForMdBatch();
			//先调用补充任务的方法
			supplementBatchData();
			//再调用全局生成的任务
			generalBatchDataList();
			return repeatResult.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * 说明: 更新批次的数量 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年9月9日 上午10:38:46 </pre>
	 * @param 
	 * @return void 说明
	 */
	@Override
	public void updateBatchCountForMdBatch() {
	   List<String> batchNoList = this.mybatisDao01.getSession().selectList("mdData.getBatchDataInfoByBatchCountIsNull");
	   if (!CollectionUtils.isEmpty(batchNoList)) {
		   for (String batchNo : batchNoList) {
			   int updateCount = this.mybatisDao01.getSession().update("mdData.updateBatchDataInfoByBatchCountIsNull", batchNo);
		       LogUtils.info("updateBatchCountForMdBatch updateCount:"+updateCount);
		   }
	   }
	}
	
	/**
	 * 说明:过滤品牌敏感词 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年9月1日 下午4:27:54 </pre>
	 * @param 
	 * @return void 说明
	 */
	@Override
	public void fileterPingPaiGanCi(String uuid, String dataTitle) {
		StringBuffer sBuffer = new StringBuffer();
		 Map<String, Object> parameter = new HashMap<String,Object>();
			parameter.put("dataTitle", dataTitle);
			parameter.put("parentUUID", "20180901153619147993375");
		 List<String> matchResultList = mybatisDao01.getSession().selectList("mdData.matchResultList", parameter);
		 if (!CollectionUtils.isEmpty(matchResultList)) {
			 for (String dicName : matchResultList) {
				 if (StringUtils.contains(dataTitle, dicName)) {
					 sBuffer.append(dicName+",");
				 }
			 }
			 if (StringUtils.isNotBlank(sBuffer.toString())) {
		         parameter.clear();
		         parameter.put("updateType", "pingPaiGanCi");
		         parameter.put("pingPaiGanCi", sBuffer.toString());
		         parameter.put("uuid", uuid);
		         mybatisDao01.getSession().update("mdData.updateGanCi", parameter);
			 }
		 }else {
			 parameter.put("pingPaiGanCi", "");
			 parameter.put("updateType", "pingPaiGanCi");
	         parameter.put("uuid", uuid);
	         mybatisDao01.getSession().update("mdData.updateGanCi", parameter);
		}
	}
	
	public String fileterPingPaiGanCi(String dataTitle) {
		StringBuffer sBuffer = new StringBuffer();
		 Map<String, Object> parameter = new HashMap<String,Object>();
			parameter.put("dataTitle", dataTitle);
			parameter.put("parentUUID", "20180901153619147993375");
		 List<String> matchResultList = mybatisDao01.getSession().selectList("mdData.matchResultList", parameter);
		 if (!CollectionUtils.isEmpty(matchResultList)) {
			 for (String dicName : matchResultList) {
				 if (StringUtils.contains(dataTitle, dicName)) {
					 sBuffer.append(dicName+",");
				 }
			 }
		     return sBuffer.toString();
		 }
		 return "";
	}

	/**
	 * 说明:过滤标题敏感词 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年9月1日 下午4:27:54 </pre>
	 * @param 
	 * @return void 说明
	 */
	@Override
	public void fileterTitleGanCi(String uuid, String dataTitle) {
		 StringBuffer sBuffer = new StringBuffer();
		 Map<String, Object> parameter = new HashMap<String,Object>();
			parameter.put("dataTitle", dataTitle);
			parameter.put("parentUUID", "20180901153619037752948");
		 List<String> matchResultList = mybatisDao01.getSession().selectList("mdData.matchResultList", parameter);
		 if (!CollectionUtils.isEmpty(matchResultList)) {
			 for (String dicName : matchResultList) {
				 if (StringUtils.contains(dataTitle, dicName)) {
					 sBuffer.append(dicName+",");
				 }
			 }
			 if (StringUtils.isNotBlank(sBuffer.toString())) {
		         parameter.clear();
		         parameter.put("titleGanCi", sBuffer.toString());
		         parameter.put("uuid", uuid);
		         parameter.put("updateType", "titleGanCi");
		         mybatisDao01.getSession().update("mdData.updateGanCi", parameter);
			 }
		 }else {
			 parameter.put("titleGanCi","");
	         parameter.put("uuid", uuid);
	         parameter.put("updateType", "titleGanCi");
	         mybatisDao01.getSession().update("mdData.updateGanCi", parameter);
		 }
	}
	
	public String fileterTitleGanCi(String dataTitle) {
		 StringBuffer sBuffer = new StringBuffer();
		 Map<String, Object> parameter = new HashMap<String,Object>();
			parameter.put("dataTitle", dataTitle);
			parameter.put("parentUUID", "20180901153619037752948");
		 List<String> matchResultList = mybatisDao01.getSession().selectList("mdData.matchResultList", parameter);
		 if (!CollectionUtils.isEmpty(matchResultList)) {
			 for (String dicName : matchResultList) {
				 if (StringUtils.contains(dataTitle, dicName)) {
					 sBuffer.append(dicName+",");
				 }
			 }
			 return sBuffer.toString();
		 }
		return "";
	}

	/**
	 * 说明: 补充不满足300条的批次数据 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年8月31日 下午11:42:12 </pre>
	 * @param 
	 * @return void 说明
	 */
	@Override
	public void supplementBatchData() {
		List<Map<String, Object>> batchDataList = mybatisDao01.getSession().selectList("mdData.queryNotEnough300Data");
		if (!CollectionUtils.isEmpty(batchDataList)) {
			for (Map<String, Object> dataMap : batchDataList) {
				String batchNo = (String) dataMap.get("batchNo");
				int count = (Integer) dataMap.get("batchCount");
				int diffCount = 300-count;
				List<Map<String, Object>> mdDataList = mybatisDao01.getSession().selectList("mdData.queryMdDataCountByGroup",diffCount);
				if (!CollectionUtils.isEmpty(mdDataList)) {
					for (Map<String, Object> mdData : mdDataList) {
						int id = (Integer) mdData.get("id");
						Map<String, Object> paramMap = new HashMap<String,Object>();
						paramMap.put("batchNo",batchNo);
						paramMap.put("id",id);
						int updateCount = mybatisDao01.getSession().update("mdData.updateMdDataBatchNoById",paramMap);
						LogUtils.info("updateCount:"+updateCount);
					}
				}
			}
		}
	}

	/**
	 * 说明: 异步执行生成批次 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年8月26日 下午5:54:57 </pre>
	 * @param 
	 * @return void 说明
	 */
	//@Async
	@Override
	public void generalBatchDataList() throws InterruptedException {
		BatchDataInfo batchDataInfo = null;
		int index = 1;
		while (true) {
			List<Map<String, Object>> mdDataList = mybatisDao01.getSession().selectList("mdData.queryMdDataCountByGroup",300);
			if (CollectionUtils.isEmpty(mdDataList)) {
				break;
			}
			LogUtils.info("mdDataList["+index+"]:"+mdDataList);
			//生成批次号
			String batchNo = MathUtils.getTheOnlyStr();
			String dataUrl = "";
			for (Map<String, Object> mdData : mdDataList) {
				int id = (Integer) mdData.get("id");
				dataUrl = (String) mdData.get("dataUrl");
				Map<String, Object> paramMap = new HashMap<String,Object>();
				paramMap.put("batchNo",batchNo);
				paramMap.put("id",id);
				int updateCount = mybatisDao01.getSession().update("mdData.updateMdDataBatchNoById",paramMap);
				LogUtils.info("updateCount:"+updateCount);
			}
			batchDataInfo = new BatchDataInfo();
			batchDataInfo.setUuid(batchNo);
			batchDataInfo.setBatchDesc("第【"+index+"】个店铺");
			batchDataInfo.setCreater("系统机器人");
			batchDataInfo.setCreateTime(new Date());
			batchDataInfo.setDataType("");
			batchDataInfo.setDeleteFlag(0);
			batchDataInfo.setEditorName("");
			batchDataInfo.setEditTime(new Date());
			batchDataInfo.setFileName("batch_"+batchNo+".txt");
			batchDataInfo.setIsDownload(0);
			batchDataInfo.setBatchCount(mdDataList.size());
			batchDataInfo.setUrlId(dataUrl);
			mybatisDao01.getSession().update("mdData.insertBatchDataInfo",batchDataInfo);
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			LogUtils.info("剩余数量：第【"+index+"】个店铺");
			index++;
		}
	}
	
	/**
	 * 说明: 下载文件 <br>
	 * 编写者:lushuifa
	 * 创建时间:2018年8月27日 下午11:26:23 </pre>
	 * @param imgApp 
	 * @param fileDiskPath 
	 * @param 
	 * @return boolean 说明
	 */
	public byte[] downloadFile(String batchNo, String fileDiskPath, String imgApp) {
		String realName = AdminCacheUtils.getLoginAdminUser().getRealName();
        String sql = "update "+SqlGeneratorImpl.getTableName(BatchDataInfo.class)+" set is_download=1,editor_name='"+realName+"',edit_time=now() where uuid="+batchNo;
		super.execute(sql);
		try {
			List<MdData> mdDataList = super.queryForBeanList(MdData.class, "where batch_no='"+batchNo+"'");
			StringBuffer sb = new StringBuffer();
			for (MdData mdData : mdDataList) {
				String lines = mdData.getDataUrl()+"$$"+mdData.getDataTitle();
				sb.append(lines+"\r\n");
			}
			return sb.toString().getBytes();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 标题:删除敏感词<br>
	 * 编写者:lushuifa
	 * 创建时间:2018年9月5日 上午12:10:25 </pre>
	 * @param
	 * @return 
	 * @see com.fast.cms.service.article.MdDataService#deleteCihui(java.lang.String)
	 */
	public int deleteCihui(String mianganCi) {
		if (StringUtils.isNotBlank(mianganCi)) {
			mianganCi = mianganCi.replace(",", "");
			int deleteCount = super.getSession().delete("mdData.deleteCihui", mianganCi);
			if (deleteCount>0) {
				//重新检测词汇
				repeatCheckMianGanCi(mianganCi);
			}
			return deleteCount;
		}
		return 0;
	}
	
	public int batchDeleteCihui(String miangancis) {
		if (StringUtils.isNotBlank(miangancis)) {
			String[] mianganciArray =miangancis.split(",");
			for (String mianganCi : mianganciArray) {
				deleteCihui(mianganCi);
			}
			return mianganciArray.length;
		}
		return 0;
	}
	
	@Override
	@Async
	public void repeatCheckMianGanCi(String mianganCi) {
		HashMap<String, Object> paramMap = new HashMap<String,Object>();
		paramMap.put("mianganCi", mianganCi);
		List<Map<String, Object>> dataList = super.getSession().selectList("mdData.getMianganList",paramMap);
		for (Map<String, Object> dataMap : dataList) {
			String uuid = (String) dataMap.get("uuid");
			String dataTitle = (String) dataMap.get("dataTitle");
			fileterPingPaiGanCi(uuid, dataTitle);
			fileterTitleGanCi(uuid, dataTitle);
		}
	}
}

